首页 > 试题广场 >

最小覆盖子串

[编程题]最小覆盖子串
  • 热度指数:76733 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解


给出两个字符串 s 和 t,要求在 s 中找出最短的包含 t 中所有字符的连续子串。

数据范围:,保证s和t字符串中仅包含大小写英文字母
要求:进阶:空间复杂度 , 时间复杂度
例如:



找出的最短子串为.

注意:
如果 s 中没有包含 t 中所有字符的子串,返回空字符串 “”;
满足条件的子串可能有很多,但是题目保证满足条件的最短的子串唯一。

示例1

输入

"XDOYEZODEYXNZ","XYZ"

输出

"YXNZ"
示例2

输入

"abcAbA","AA"

输出

"AbA"
class Solution:
    def minWindow(self , S: str, T: str) -> str:
        # write code here
        dict_ = {}
        min_len = 10001
        n = len(S)
        for i in T:
            dict_[i] = T.count(i)
        l, r = 0, 0
        counter = len(T)
        ans_l, ans_r = 0, 0
        while r<n:
            if S[r] in dict_ and dict_[S[r]]>0:
                counter-=1
            if S[r] in dict_:
                dict_[S[r]]-=1
            if counter==0:
                while l<n:
                    if S[l] in dict_ and dict_[S[l]]<0:
                        dict_[S[l]]+=1
                    elif S[l] in dict_ and dict_[S[l]]==0:
                        if r-l+1<min_len:
                            min_len = r-l+1
                            ans_l, ans_r = l, r+1
                        counter+=1
                        dict_[S[l]]+=1
                        l+=1
                        break
                    l+=1
            
            r+=1
        return S[ans_l:ans_r]

发表于 2022-08-03 11:17:59 回复(0)
class Solution:
    def minWindow(self , S: str, T: str) -> str:
        # write code here
        if len(S)==0&nbs***bsp;len(T)==0&nbs***bsp;len(S) < len(T):
            return ""
        # 准备两本字典,分别记录T的词频和S子串的词频
        freqT = {}
        freqS = {}
        for string in T:
            if string not in freqT.keys():
                freqT[string] = 1
            else:
                freqT[string] += 1
        q = [] # 准备队列一个,依次记录在S中发现的T字符索引
        cnt = 0 # 计数器, 记录T中字符是否被查全
        length = len(S) + 1
        j = 0
        tail = 0
        head = 0
        while j < len(S):
            if S[j] in freqT.keys():
                # 统计S中子串词频
                if S[j] not in freqS.keys():
                    freqS[S[j]] = 1
                else:
                    freqS[S[j]] += 1
                # 当S的某个单词词频《=T时,表明单词没有查全,计数器加 1,
                if freqS[S[j]] <= freqT[S[j]]:
                    cnt += 1
                # 字符索引入队
                q.append(j)
                # 当单词查全时, 记录长度,同时队头出队,出队单词词频减 1
                while cnt >= len(T):
                    if q[-1] - q[0] + 1 < length:
                        head = q[0]
                        tail = q[-1]
                        length = tail - head + 1
                    s = q.pop(0)
                    freqS[S[s]] -= 1
                    if freqS[S[s]] < freqT[S[s]]:
                        cnt -= 1
            j += 1
        if length == len(S) + 1:
            return ""
        else:
            return S[head:tail+1]

发表于 2022-06-22 10:10:11 回复(0)

哈希表 + 双指针的滑动窗口,找到包含T的所有字符,缩小窗口找到最小子串
时间复杂度:O(len(T)*len(S)+len(T)) 空间复杂度:O(len(T))

class Solution:
    def check(self, mp):
        for key, value in mp.items():
            if value < 0:
                return False
        return True

    def minWindow(self , S: str, T: str) -> str:
        mp = {}
        low = 0
        high = 0
        left = -1
        right = -1
        len_ = len(S) + 1
        for i in T:
            if i in mp:
                mp[i] -= 1
            else:
                mp[i] = -1
        for j in range(len(S)):
            if S[high] in mp:
                mp[S[high]] += 1
                while self.check(mp):
                    if len_ > high - low + 1:
                        len_ = high - low + 1
                        left = low
                        right = high
                    if S[low] in mp:
                        mp[S[low]] -= 1
                    low += 1
            high += 1
        if left == -1:
            return ''
        return S[left:right+1]
发表于 2022-05-27 10:33:33 回复(0)
class Solution:
    def minWindow(self , S: str, T: str) -> str:
        # write code here
        
        n = len(S)
        m = len(T)
        if (n == 0&nbs***bsp;m == 0):
            return ''

        # 使用双指针,表示用来匹配T的S子串的左右索引
        index_1 = 0
        index_2 = -1
        
        # min为最短长度子串的左索引, min_len为最短长度
        min = 0
        min_len = n+1
        
        # pattern用字典来记录T中所有字符的出现次数
        # d用来记录双指针中间子串包含pattern中字符的次数
        # lack表示子串要包含T还缺少哪些字符,缺多少个
        d = {}
        pattern = {}
        lack = {}
        
        
        # 把lack和pattern初始化为T中各个字符的出现次数
        # d初始化为0次
        for i in T:
            if i not in d:
                lack[i] = 1
                pattern[i] = 1
                d[i] = 0
            else:
                lack[i] += 1
                pattern[i] += 1
        
        # 如果右指针超过了S的长度,结束循环
        while (index_2 < n):     

            # lack为空也就是S的子串还没有包含所有T
            if (lack != {}):
                
                # 考虑右指针右移的新增字符
                index_2 = index_2 + 1
                if (index_2 >= n):
                    break
                # 如果新增字符在T中
                if (S[index_2] in pattern):
                    # 则d中对应字符的次数加1,lack中对应的减1,
                    # 如果lack中值为0,则表明不再缺了,删除键值
                    d[S[index_2]] += 1
                    if (S[index_2] in lack):
                        lack[S[index_2]] -= 1               
                        if (lack[S[index_2]] == 0):
                            lack.pop(S[index_2])
            
            # 如果lack为空,也就是子串已经包含T
            # 左指针右移,逐渐缩小区间
            else:
                if (index_2 - index_1 + 1 < min_len):
                    min_len = index_2 - index_1 + 1
                    min = index_1
                    
                # 如果删掉的字符在pattern中,则d的对应次数减1
                # 如果d中的出现次数少于pattern中的出现次数
                # 说明子串中该字符比T的要少了,缺少这个字符
                if (S[index_1] in pattern):
                    d[S[index_1]] -= 1
                    if (d[S[index_1]] < pattern[S[index_1]]):
                        lack[S[index_1]] = 1

                index_1 += 1
                
        if (min_len == n+1):
            return ''
        
        return (S[min: min+min_len])

发表于 2022-04-15 10:28:12 回复(0)